#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <asm/uaccess.h>


static int major;
static struct class *class;
static struct i2c_client *oled_client;


/* buf[0] : addr
 * buf[1] : data
 */
static ssize_t oled_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
{
	unsigned char ker_buf[2];
	unsigned char cmd_or_data, data;

	copy_from_user(ker_buf, buf, 2);
	cmd_or_data = ker_buf[0];
	data = ker_buf[1];

	//printk("addr = 0x%02x, data = 0x%02x\n", cmd_or_data, data);

	if (!i2c_smbus_write_byte_data(oled_client, cmd_or_data, data))
		return 2;
	else
		return -EIO;	
}

static struct file_operations oled_fops = {
	.owner = THIS_MODULE,
	.write = oled_write,
};

static int __devinit oled_probe(struct i2c_client *client,
				  const struct i2c_device_id *id)
{
	oled_client = client;
		
	//printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
	major = register_chrdev(0, "oled", &oled_fops);
	class = class_create(THIS_MODULE, "oled");
	device_create(class, NULL, MKDEV(major, 0), NULL, "oled"); /* /dev/oled */
	
	return 0;
}

static int __devexit oled_remove(struct i2c_client *client)
{
	//printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
	device_destroy(class, MKDEV(major, 0));
	class_destroy(class);
	unregister_chrdev(major, "oled");
		
	return 0;
}

static const struct i2c_device_id oled_id_table[] = {
	{ "oled", 0 },
	{}
};


/* 1. 分配/设置i2c_driver */
static struct i2c_driver oled_driver = {
	.driver	= {
		.name	= "i2c_oled",
		.owner	= THIS_MODULE,
	},
	.probe		= oled_probe,
	.remove		= __devexit_p(oled_remove),
	.id_table	= oled_id_table,
};

static int oled_drv_init(void)
{
	/* 2. 注册i2c_driver */
	return i2c_add_driver(&oled_driver);	
}

static void oled_drv_exit(void)
{
	i2c_del_driver(&oled_driver);
}


module_init(oled_drv_init);
module_exit(oled_drv_exit);
MODULE_LICENSE("GPL");


